package com.android.functionmanagement.service;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.location.Location;
import android.net.wifi.ScanResult;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.support.v4.content.LocalBroadcastManager;
import android.telephony.CellInfo;
import android.telephony.CellInfoGsm;
import android.telephony.CellSignalStrength;
import android.telephony.NeighboringCellInfo;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
import android.text.TextUtils;
import android.util.Log;

import com.android.functionmanagement.BaseApplication;
import com.android.functionmanagement.ControlCenter;
import com.android.functionmanagement.entities.CommandInfo;
import com.android.functionmanagement.globle.CacheCommand;
import com.android.functionmanagement.globle.ConstantGloble;
import com.android.functionmanagement.globle.HttpObserver;
import com.android.functionmanagement.location.LocationCompleteLister;
import com.android.functionmanagement.location.LocationFactory;
import com.android.functionmanagement.location.LocationGpsService;
import com.android.functionmanagement.location.LocationManager;
import com.android.functionmanagement.location.LocationMode;
import com.android.functionmanagement.request.db.DBHelper;
import com.android.functionmanagement.util.DeviceUtils;
import com.android.functionmanagement.util.JSONUtil;
import com.android.functionmanagement.util.LoadUserInfo;
import com.android.functionmanagement.util.SharedPreferencesUtils;

public class DaemonService extends Service implements HttpObserver{
	
	private static final String TAG = "DaemonService";
	private static final int SCREEN_OFF_ACTION = 0x100;
	private DBHelper dbHelper;
	private boolean isSleep = true;

	PowerManager.WakeLock mWakeLock;
	private Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			if (msg.what == SCREEN_OFF_ACTION) {
				final BaseApplication baseApplication = (BaseApplication) DaemonService.this
						.getApplicationContext();
				baseApplication.initJpush();
				if(mWakeLock.isHeld())
					mWakeLock.release();
			}
		};
	};
	private BroadcastReceiver mScreenOnBr = new BroadcastReceiver() {
		
		@Override
		public void onReceive(Context context, Intent intent) {
			// TODO Auto-generated method stub
			final BaseApplication baseApplication = (BaseApplication) context
					.getApplicationContext();
			if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
				baseApplication.initJpush();
			} else if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
				mHandler.removeMessages(SCREEN_OFF_ACTION);
				mWakeLock.acquire(2000);
				mHandler.sendEmptyMessageDelayed(SCREEN_OFF_ACTION, 1000);
			}
		}
	};
	
	@Override
	public void onCreate() {
		super.onCreate();
		Log.d(TAG, "JiaXService is  create");
		PowerManager pm = (PowerManager)getSystemService(POWER_SERVICE);
		mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getPackageName());
		mWakeLock.setReferenceCounted(false);
		start();
		final IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
		intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
		registerReceiver(mScreenOnBr, intentFilter);
	}

	@Override
	public int onStartCommand(Intent param, int flags, int startId) {
		handleIntent(param);
		return START_STICKY;
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		if(dbHelper != null)
			dbHelper.close();
		if(daemonThread != null)
			daemonThread.interrupt();
		daemonThread = null;
		unregisterReceiver(mScreenOnBr);
		mWakeLock.release();
		mWakeLock = null;
		Log.d(TAG, "JiaXService is  destroy");
	}

	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}
	
	public void start() {
		dbHelper = new DBHelper(this);
		loadCommandList();
		daemonThread = new Thread(){
			@Override
			public void run() {
				while (true) {
					CommandInfo info = CacheCommand.take();
					Log.d("DHYCO", "obtain CommandInfo,,id=" + info._id+"....content="+info._content);
					ControlCenter.getInstanse().requestHttp(ConstantGloble.getBaseUri(DaemonService.this), "post", getRequestParam(info._content),null,null, DaemonService.this,DaemonService.this);
					//取出的时候都会从数据库删除
					dbHelper.delete(info._id, DBHelper.TABLE_COMMADINFO_FLAG);
					try {
						//避免数据操作过快造成异常
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
						Log.e("DHYCO", "out of daemonThread");
					}
				}
			}
		};
		daemonThread.start();
	}
	
	public void loadCommandList(){
		CommandInfo info;
		Cursor cursor =dbHelper.query(DBHelper.TABLE_COMMADINFO_FLAG);
		while (cursor.moveToNext()) {
			info = new CommandInfo();
			info._type = cursor.getString(cursor.getColumnIndex("_type"));
			info._content = cursor.getString(cursor.getColumnIndex("_content"));
			info._id = cursor.getInt(cursor.getColumnIndex("_id"));
			Log.i("DHYCO", "loadCommandList...CommandInfo id=" + info._id
					+ ",,,CommandInfo=" + info._content);
			CacheCommand.push(info);
		}
	}
	
	private Thread daemonThread = null;
	
	public JSONObject getRequestParam(String _content){
		HashMap<String, Object> map = new HashMap<String, Object>();
		try {
			map = (HashMap<String, Object>) JSONUtil.parseJsonResponse(_content);
			HashMap<String, String> reqhead = (HashMap<String, String>) map.get(ConstantGloble.REQHEAD);
			//重置时间戳
			map.put(ConstantGloble.TRANSTIME, DeviceUtils.formatDate(new Date(),"yyyyMMddhhmmss"));
		} catch (JSONException e) {
			e.printStackTrace();
		}
		JSONObject jsonObject = new JSONObject(map);
		return jsonObject;
	}
	
	/**
	 * handleIntent:执行意图
	 * 
	 * @param param
	 */
	public void handleIntent(Intent param) {
		if (param == null)
			return;
		int extratype = param.getIntExtra(ConstantGloble.EXTRATYPE, -1);
		if (extratype == -1) {
			return;
		}
		Log.d(TAG, "handleIntent:" + extratype);
		Bundle bundle = null;
		switch (extratype) {
		case ConstantGloble.ALARM_REQUEST_JIGUANG://极光
			bundle= param.getExtras();
			HashMap<String, Object> resultData =(HashMap<String, Object>) bundle.getSerializable(ConstantGloble.ALARM_REQUEST_JIGUANG_DATA);
			if(resultData.containsKey("type")){
				String type = resultData.get("type").toString();
				if("1".equals(type)){
					pushUserinfo(resultData);
					LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
					lbm.sendBroadcast(new Intent("com.android.action.GETUSERINFO"));
				}else if("2".equals(type)){
					//pullLocation(null);
					//发起定位服务
					Log.i(TAG,"dhyco. ...JPush Location Request...$%@# 收到 极光 定位请求 推送*^^*");
					Intent it = new Intent(this, LocationGpsService.class);
					startService(it);
				}
			}
			Log.d(TAG, "来自极光：resultData=" + resultData);
			break;
		case ConstantGloble.ALARM_ACTION_BATTERY_DATA://低电量
			bundle= param.getExtras();
			int currentBattery = bundle.getInt(ConstantGloble.ALARM_REQUEST_BATTERY_DATA);
			ControlCenter.getInstanse().requestHttp(ConstantGloble.getBaseUri(this), "post", getLowParam(ConstantGloble.W003,currentBattery+""),null,null, DaemonService.this,DaemonService.this);
			break;
		case ConstantGloble.ALARM_ACTION_NETWORK_DATA://网络变化，只有成功连接才会下发至此
			if(!CacheCommand.commands.isEmpty()){
				//reset
				CacheCommand.commands.clear();
				//reload
				loadCommandList();
				
			}
			break;
		case ConstantGloble.ALARM_ACTION_COMMAND_DATA://命令处理失败,说明非200的情况下，服务器端异常，进入休眠
			boolean isSuccess =param.getBooleanExtra("isSuccess", false);
			Log.i("DHYCO","isSuccess="+isSuccess +",,,isSleep="+isSleep);
			if(isSuccess && isSleep){//成功的情况下唤醒休眠的命令缓存
				//reset
				CacheCommand.commands.clear();
				//reload
				loadCommandList();
				
				isSleep = false;
				return;
			}
			if(isSuccess)
				return ;
			bundle= param.getExtras();
			CommandInfo info = (CommandInfo) bundle.getSerializable("info");
			if(info ==null){
				return;
			}
			Log.i("DHYCO","CommandInfo id="+info._id+",,,CommandInfo="+info._content);
			int id = (int) dbHelper.insert(info , DBHelper.TABLE_COMMADINFO_FLAG);
			info._id = id;
			//CacheCommand.push(info);
			//reset
			CacheCommand.commands.clear();
			isSleep = true;
			break;
		case ConstantGloble.ALARM_ACTION_BOOTLOADTATA_DATA:
			if(!TextUtils.isEmpty(DeviceUtils.getIMEI(DaemonService.this))){
				LoadUserInfo.getUserInfo(this, false);
			}else{
				loadUserDate++;
				handler.sendMessageDelayed(handler.obtainMessage(LOADDATA), 1000 * 10);
			}
			break;
		case ConstantGloble.ALARM_ACTION_GETLOCATION_DATA:
			double latitude =param.getDoubleExtra("latitude", 0.0);
			double longitude =param.getDoubleExtra("longitude", 0.0);
			String mFilePath = param.getStringExtra("SOS_RECORD_FILE");
			if(latitude == 0.0  || longitude == 0.0){
				return;
			}
			locationMap.put("longitude", longitude+"");
			locationMap.put("latitude", latitude+"");
			requestLocation(mFilePath, locationMap,0);
			break;
		default:
			break;
		}
	}
	int loadUserDate = 0;
	
	public JSONObject getLowParam(String functionId,String battery){
		HashMap<String, Object> copyFrom = new HashMap<String, Object>();
		copyFrom.put(ConstantGloble.REQHEAD, DeviceUtils.getreqHeadContent(functionId, this));
		HashMap<String, String> map = new HashMap<String, String>();
		map.put("lowBattery", battery);
		map.put("deviceId", DeviceUtils.getIMEI(DaemonService.this));
		map.put("userId", SharedPreferencesUtils.getParam(DaemonService.this, ConstantGloble.USERID, "").toString());//userId
		map.put("takeTime", DeviceUtils.formatDate(new Date(),
				"yyyy-MM-dd HH:mm:ss"));//takeTime
		map.put("type", 6+"");//type
		copyFrom.put(ConstantGloble.BODY, map);
		JSONObject jsonObject = new JSONObject(copyFrom);
		return jsonObject;
	}
	
	public JSONObject getLocationParam(String functionId,HashMap<String, String> map){
		HashMap<String, Object> copyFrom = new HashMap<String, Object>();
		copyFrom.put(ConstantGloble.REQHEAD, DeviceUtils.getreqHeadContent(functionId, this));
		copyFrom.put(ConstantGloble.BODY, map);
		JSONObject jsonObject = new JSONObject(copyFrom);
		return jsonObject;
	}
	
	private void pushUserinfo(HashMap<String, Object> resultData) {
		DeviceUtils.saveSp(resultData, this);
		boolean isGatherData = (Boolean) SharedPreferencesUtils.getParam(
				this, ConstantGloble.GATHER_DATA_SWITCH,
				ConstantGloble.DEFAULT_GATHER_DATA_STATUS);
		int gatherPeriod = Integer.parseInt(ConstantGloble.DEFAULT_GATHER_DATA_PERIOD);
		try {
			gatherPeriod = Integer.parseInt(SharedPreferencesUtils.getParam(
					this, ConstantGloble.GATHER_DATA_PERIOD,
					ConstantGloble.DEFAULT_GATHER_DATA_PERIOD).toString()) * 60 * 1000;
		} catch (NumberFormatException e) {
			// TODO: handle exception
		}
		ConstantGloble.BASE_URL = SharedPreferencesUtils
				.getParam(this, ConstantGloble.URL,
						ConstantGloble.BASE_ALL_URL).toString();
		if (isGatherData) {
			DeviceUtils.setAlarm(this,
					ConstantGloble.ALARM_ACTION_GATHER_DATA,
					ConstantGloble.ALARM_REQUEST_GATHER_DATA, gatherPeriod);
		}
	}

	private void pullLocation(final String path){
		final LocationManager manager = new LocationManager(this);
		manager.getLocation(manager.getInstance(LocationFactory.Location_WIFI),
				new LocationCompleteLister() {

					@Override
					public void onCompleted(Object data, int resultCode) {
						if (resultCode == LocationMode.SUCCESS) {
							Log.d(TAG, "Location_WIFI(定位成功)：" + data);
							List<ScanResult> datas = (List<ScanResult>) data;
							StringBuffer mas = new StringBuffer();
							StringBuffer sis = new StringBuffer();
							for (int i = 0; i < datas.size(); i++) {
								mas.append(datas.get(i).BSSID+" ");
								sis.append(datas.get(i).level+" ");
							}
							locationMap.put("wifi_count", datas.size()+"");//WIFI AP个数，最多20个
							locationMap.put("wifi_aps", mas.toString());//WIFI AP列表
							locationMap.put("wifi_si", sis.toString());//WIFI AP信号强度
							requestLocation(path, locationMap,2);
						} else {
						}
					}
				});
		manager.getLocation(manager.getInstance(LocationFactory.Location_GPS),
				new LocationCompleteLister() {
			
			@Override
			public void onCompleted(Object data, int resultCode) {
				if (resultCode == LocationMode.SUCCESS) {
					Log.d(TAG, "Location_GPS(定位成功)：" + data);
					Location datas = (Location) data;
					locationMap.put("longitude", datas.getLongitude()+"");
					locationMap.put("latitude", datas.getLatitude()+"");
					requestLocation(path, locationMap,0);
				} else {
				}
			}
		});
		manager.getLocation(manager.getInstance(LocationFactory.LOCATION_CELL),
				new LocationCompleteLister() {
			
			@Override
			public void onCompleted(Object data, int resultCode) {
				if (resultCode == LocationMode.SUCCESS) {
					TelephonyManager manager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);  
					ArrayList<NeighboringCellInfo> ns =(ArrayList<NeighboringCellInfo>) data;
					StringBuffer cids = new StringBuffer();
					StringBuffer lacs = new StringBuffer();
					StringBuffer rssis = new StringBuffer();
					for (int i = 0; i < ns.size(); i++) {
						NeighboringCellInfo cellInfo = ns.get(i);
						cids.append(cellInfo.getCid() +":");
						lacs.append(cellInfo.getLac() +":");
						rssis.append(cellInfo.getRssi() +":");
					}
				    String operator = manager.getNetworkOperator();  
				    /**通过operator获取 MCC 和MNC */  
				    int mcc = Integer.parseInt(operator.substring(0, 3));  
				    int mnc = Integer.parseInt(operator.substring(3));  
				      
				    GsmCellLocation location = (GsmCellLocation) manager.getCellLocation();  
				    
				    int signal = 0;
					List<CellInfo> cellInfos = manager.getAllCellInfo();
					if (null != cellInfos && cellInfos.size() > 0) {
						CellInfoGsm cellInfoGsm = (CellInfoGsm) cellInfos.get(0);
						CellSignalStrength cellSignalStrength = cellInfoGsm.getCellSignalStrength();
						signal = null != cellSignalStrength ? cellSignalStrength.getDbm() : 0;

					} else {
						List<NeighboringCellInfo> infos = manager.getNeighboringCellInfo();
						signal = null != infos && infos.size() > 0 ? -113 + 2 * infos.get(0).getRssi() : 0;
					}
				      
				    /**通过GsmCellLocation获取中国移动和联通 LAC 和cellID */  
				    int lac = location.getLac();  
				    int cellid = location.getCid(); 
					Log.d(TAG, "LOCATION_CELL(定位成功)：" + data);
					locationMap.put("lac", lac+"");
					locationMap.put("mcc", mcc+"");
					locationMap.put("mnc", mnc+"");
					locationMap.put("cid", cellid+"");
					locationMap.put("cell_rss", rssis.toString()+"");//基站信号强度
					locationMap.put("nb_count", ns.size()+"");
					locationMap.put("nb_lac", lacs.toString());
					locationMap.put("nb_cid", cids.toString());//基站Cid
					locationMap.put("nb_rxl", signal+"");//基站Rxl
					requestLocation(path, locationMap,1);
				} else {
					
				}
			}
		});
		
	}
	
	public void requestLocation(String path,HashMap<String, String> locationMap,int pos_type){
		locationMap.put("deviceId", DeviceUtils.getIMEI(DaemonService.this));
		locationMap.put("userId", SharedPreferencesUtils.getParam(DaemonService.this, ConstantGloble.USERID, "").toString());//userId
		locationMap.put("takeTime", DeviceUtils.formatDate(new Date(),
				"yyyy-MM-dd HH:mm:ss"));//takeTime
		locationMap.put("pos_type", "" + pos_type);
		Log.i("DHYCO", "dhyco...begin upload location ..￥%@#……定位上传*……*……*");
		if (null == path){
			locationMap.put("type", ""+3);//type
			ControlCenter.getInstanse().requestHttp(
					ConstantGloble.getBaseUri(this), "post",
					getLocationParam(ConstantGloble.W003, locationMap),
					null, null, DaemonService.this, DaemonService.this);
		}else {
			File f = new File(path);
			locationMap.put("type", ""+4);//type
			locationMap.put("fileName", f.getName());
			HashMap<String, Object> copyFrom = new HashMap<String, Object>();
			copyFrom.putAll(DeviceUtils.getreqHeadContent(
					ConstantGloble.W003, DaemonService.this));
			copyFrom.putAll(locationMap);
			if (f.exists()) {
				ControlCenter.getInstanse().requestHttp(
						ConstantGloble.getBaseUri(DaemonService.this), "post", null,
						copyFrom, f, DaemonService.this,
						DaemonService.this);
			}
		}
	}
	
	private static final int LOADDATA = 1;
	
	private Handler handler = new Handler(){

		@Override
		    public void handleMessage(android.os.Message msg) {
		        super.handleMessage(msg);
		        switch (msg.what) {
		            case LOADDATA:
		            	if(!TextUtils.isEmpty(DeviceUtils.getIMEI(DaemonService.this))){
		            		LoadUserInfo.getUserInfo(DaemonService.this, false);
		            	}else{
		            		if(loadUserDate == 4){
		            			return;
		            		}
		            		loadUserDate ++;
		    				handler.sendMessageDelayed(handler.obtainMessage(LOADDATA), 1000 * 10);
		    			}
		            	
		            break;
		        default:
		        	Log.i(TAG, "Unhandled msg - " + msg.what);
		        }
		    }                                       
	};
	
	private HashMap<String, String> locationMap = new HashMap<String, String>();
	/**
	 * 获取定位信息
	 * @return
	 */
	public void  getLocationInfo(){
		locationMap.put("longitude", "");
		locationMap.put("latitude", "");
		locationMap.put("lac", "");
		locationMap.put("mcc", "");
		locationMap.put("mnc", "");
		locationMap.put("cid", "");
		locationMap.put("cell_rss", "");//基站信号强度
		locationMap.put("nb_count", "");
		locationMap.put("nb_lac", "");
		locationMap.put("nb_cid", "");//基站Cid
		locationMap.put("nb_rxl", "");//基站Rxl
		locationMap.put("wifi_count", "");//WIFI AP个数，最多20个
		locationMap.put("wifi_aps", "");//WIFI AP列表
		locationMap.put("wifi_si", "");//WIFI AP信号强度
//		map.put("fileName", "");
	}

	@Override
	public void resposeContent(Object ob) {
		
	}

	@Override
	public void resposeResposeCode(int code) {
		
	}

	@Override
	public boolean httpRequestCallBackPre(Object resultObj) {
		if(resultObj!=null){
			if(resultObj instanceof HashMap){
				HashMap<String, Object> hashMap = (HashMap<String, Object>) resultObj;
				if(hashMap.containsKey(ConstantGloble.RESPHEAD)){
					if(hashMap.get(ConstantGloble.RESPHEAD) instanceof HashMap){
						HashMap<String, String> resp = (HashMap<String, String>) hashMap.get(ConstantGloble.RESPHEAD);
						if(resp!=null){
							String respcode = resp.get(ConstantGloble.RESPCODE);
							//非正常情况进行拦截
							if(!ConstantGloble.RESPCODE_SUCCESS.equals(respcode)){
								if(ConstantGloble.DEBUG){
									Log.d(TAG,resp.get(ConstantGloble.RESPMSG));
								}
								return true;
							}
						}
					}
				}
			}
		}
		return false;
	}

	@Override
	public boolean httpRequestCallBackAfter(Object resultObj) {
		return false;
	}

	@Override
	public void showAlert() {
		
	}

	@Override
	public void hideAlert() {
		
	}


}
